home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Text / Edit / GoldED-Demo / installdata / golded / developer / api / examples / startup / funcs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-03  |  4.3 KB  |  202 lines

  1. /* -----------------------------------------------------------------------------
  2.  
  3.  startup.api ©1999 Dietmar Eilert
  4.  
  5.  API plug-in. Runs a rexx macro specified by the user (as startup argument).
  6.  Dice:
  7.  
  8.  DMAKE
  9.  
  10.  -------------------------------------------------------------------------------
  11.  
  12. */
  13.  
  14. #include "defs.h"
  15.  
  16. /// "prototypes"
  17.  
  18. // library functions
  19.  
  20. Prototype LibCall struct APIClient *APIMountClient(__A0 struct APIMessage *, __A1 char *);
  21. Prototype LibCall void              APICloseClient(__A0 struct APIClient  *, __A1 struct APIMessage *);
  22. Prototype LibCall void              APIBriefClient(__A0 struct APIClient  *, __A1 struct APIMessage *);
  23. Prototype LibCall void              APIFree       (__A0 struct APIClient  *, __A1 struct APIOrder   *);
  24.  
  25. // private
  26.  
  27. Prototype ULONG *SendRexxCommand(UBYTE *, UBYTE *, struct MessagePort *);
  28. Prototype void   StartupHandler(void);
  29.  
  30. // globals
  31.  
  32. UWORD Handlers;
  33.  
  34. ///
  35. /// "library functions"
  36.  
  37. LibCall struct APIClient *
  38. APIMountClient(__A0 struct APIMessage *apiMsg, __A1 char *args)
  39. {
  40.     static struct APIClient apiClient;
  41.  
  42.     apiClient.api_APIVersion = API_INTERFACE_VERSION;
  43.     apiClient.api_Version    = 1;
  44.     apiClient.api_Name       = "Startup";
  45.     apiClient.api_Info       = "API example";
  46.     apiClient.api_Commands   = NULL;
  47.     apiClient.api_Serial     = 0;
  48.     apiClient.api_Classes    = API_CLASS_SYSTEM;
  49.     apiClient.api_Area       = NULL;
  50.  
  51.     // <args> names the macro to be executed
  52.  
  53.     if (args && *args) {
  54.  
  55.         UBYTE *command;
  56.  
  57.         if (command = AllocVec(strlen(args) + 1, MEMF_CLEAR | MEMF_PUBLIC)) {
  58.  
  59.             struct Task *task;
  60.  
  61.             Forbid();
  62.  
  63.             if (task = (struct Task *)CreateNewProcTags(NP_Entry, (APTR)StartupHandler, NP_Name, "STARTUP", NP_Priority, 1, TAG_DONE)) {
  64.  
  65.                 ++Handlers;
  66.  
  67.                 task->tc_UserData = (APTR)strcpy(command, args);
  68.             }
  69.  
  70.             Permit();
  71.         }
  72.  
  73.     }
  74.  
  75.     return(&apiClient);
  76. }
  77.  
  78. LibCall void
  79. APICloseClient(__A0 struct APIClient *handle, __A1 struct APIMessage *apiMsg)
  80. {
  81.     // wait for termination of running tasks
  82.  
  83.     while (Handlers)
  84.  
  85.         Delay(25);
  86. }
  87.  
  88. LibCall void
  89. APIBriefClient(__A0 struct APIClient *handle, __A1 struct APIMessage *apiMsg)
  90. {
  91.     // ignore notifies
  92. }
  93.  
  94. LibCall void
  95. APIFree(__A0 struct APIClient *handle, __A1 struct APIOrder *apiOrder)
  96. {
  97.     // no ressources to be freed
  98. }
  99.  
  100. ///
  101. /// "rexx"
  102.  
  103. /* ---------------------------------- SendRexxCommand -------------------------
  104.  
  105.  Send ARexx message & wait for answer. Return pointer to result or NULL.
  106.  
  107. */
  108.  
  109. __geta4 ULONG *
  110. SendRexxCommand(port, cmd, replyPort)
  111.  
  112. UBYTE              *port;
  113. UBYTE              *cmd;
  114. struct MessagePort *replyPort;
  115. {
  116.     struct MsgPort *rexxport;
  117.  
  118.     Forbid();
  119.  
  120.     if (rexxport = FindPort(port)) {
  121.  
  122.         struct RexxMsg *rexxMsg, *answer;
  123.  
  124.         if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
  125.  
  126.             if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
  127.  
  128.                 static ULONG result;
  129.  
  130.                 rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
  131.  
  132.                 PutMsg(rexxport, &rexxMsg->rm_Node);
  133.  
  134.                 do {
  135.  
  136.                     WaitPort(replyPort);
  137.  
  138.                     if (answer = (struct RexxMsg *)GetMsg(replyPort))
  139.  
  140.                         result = answer->rm_Result1;
  141.  
  142.                 } while (!answer);
  143.  
  144.                 Permit();
  145.  
  146.                 if (answer->rm_Result1 == RC_OK)
  147.  
  148.                     if (answer->rm_Result2)
  149.  
  150.                         DeleteArgstring((UBYTE *)answer->rm_Result2);
  151.  
  152.                 DeleteArgstring((UBYTE *)ARG0(answer));
  153.  
  154.                 DeleteRexxMsg(answer);
  155.  
  156.                 return(&result);
  157.             }
  158.         }
  159.     }
  160.  
  161.     Permit();
  162.  
  163.     return(NULL);
  164. }
  165.  
  166. ///
  167. /// "startup handler"
  168.  
  169. /* ------------------------------ StartupHandler -------------------------------
  170.  
  171.  Send <command> to the ARexx server. This function runs as an asynchronous task
  172.  because plug-ins are not allowed to block the host program. The command string
  173.  is expected in the task's tc_UserData slot (it is FreeVec'ed by this function).
  174.  
  175. */
  176.  
  177. __geta4 void
  178. StartupHandler()
  179. {
  180.     UBYTE *command;
  181.  
  182.     if (command = FindTask(NULL)->tc_UserData) {
  183.  
  184.         struct MessagePort *msgPort;
  185.  
  186.         if (msgPort = CreateMsgPort()) {
  187.  
  188.             SendRexxCommand("AREXX", command, msgPort);
  189.  
  190.             DeleteMsgPort(msgPort);
  191.         }
  192.  
  193.         FreeVec(command);
  194.  
  195.         Forbid();
  196.  
  197.         --Handlers;
  198.     }
  199. }
  200.  
  201. ///
  202.